package com.yungu.swift.order.service.impl;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.yungu.swift.assets.driver.model.dto.DriverCashDto;
import com.yungu.swift.assets.driver.service.DriverCashService;
import com.yungu.swift.base.ResponseData;
import com.yungu.swift.constants.FinanceConstant;
import com.yungu.swift.order.service.WxToBankService;
import com.yungu.swift.order.utils.WxToBankBuilder;
import com.yungu.swift.system.finance.model.dto.FinanceWithdrawalDto;
import com.yungu.swift.system.finance.service.FinanceWithdrawalService;
import com.yungu.swift.system.sys.model.dto.SysAccountPlatformDto;
import com.yungu.swift.system.sys.service.SysAccountDriverService;
import com.yungu.swift.system.sys.service.SysAccountPlatformService;
import com.yungu.swift.utils.DateUtils;
import com.yungu.swift.utils.MapUtils;
import com.yungu.swift.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Description:微信转账到银行卡
 * @Author cuixiuyin
 * @Date 2018/12/29 16:10
 * @Version 1.0
 */
@Slf4j
@Service
public class WxToBankServiceImpl implements WxToBankService {
    @Reference
    private DriverCashService driverCashService;
    @Reference
    private SysAccountPlatformService sysAccountPlatformService;
    @Reference
    private FinanceWithdrawalService financeWithdrawalService;
    @Reference
    private SysAccountDriverService sysAccountDriverService;

    @Override
    public ResponseData<Map<String, String>> wxToBank(String collectAccount, String collectName, String collectBankName,
                                                      int amount, String serialNum) {
        return WxToBankBuilder.wxToBankCardData(collectAccount, collectName, collectBankName, amount, serialNum);
    }

    /**
     * 查询微信转账到银行卡状态
     *
     * @return
     */
    @Override
    @Transactional
    public ResponseData<Boolean> queryWxToBank() {
        Map<String, Object> paramMap = new HashMap<>(4);
        //查询审核成功 第三方打款状态处理中的提现数据
        //审核状态为审核成功
        paramMap.put("status", DriverCashDto.CHECK_STATUS_SUCCESS);
        //提现状态为提现中
        paramMap.put("withdrawalStatus", DriverCashDto.UNDER_WITHDRAWAL_STATUS);
        //第三方打款状态为处理中
        paramMap.put("thirdPayStatus", DriverCashDto.THIRD_STATUS_PROCESSING);
        List<DriverCashDto> driverCashDtoList = driverCashService.list(paramMap).getData();
        if (CollectionUtils.isEmpty(driverCashDtoList)) {
            log.info("没有待处理的提现信息");
            return ResponseData.buildSuccessResponse(Boolean.TRUE);
        }
        for (DriverCashDto driverCashDto : driverCashDtoList) {
            //查询打款状态
            ResponseData<Map<String, String>> wxQueryBank = WxToBankBuilder.wxQueryBank(driverCashDto.getSerialNum());
            if (!wxQueryBank.isSuccess() && wxQueryBank.getData() == null) {
                log.info("查询失败打款状态失败,提现记录表第三方流水号：{}", driverCashDto.getSerialNum());
            }
            if (!wxQueryBank.isSuccess() && wxQueryBank.getData() != null) {
                log.info("查询失败打款状态失败,提现记录表第三方流水号：{}，错误信息:{}", driverCashDto.getSerialNum(),
                        wxQueryBank.getData().get("return_msg"));
            }
            Map<String, String> wxQueryBankData = wxQueryBank.getData();
            //如果还是处理中则不做处理
            if ("PROCESSING".equals(wxQueryBankData.get("status"))) {
                continue;
            }
            //打款成功 要记录平台流水
            if ("SUCCESS".equals(wxQueryBankData.get("status"))) {
                //打款成功时间
                driverCashDto.setWithdrawalFinishTime(DateUtils.parse(wxQueryBankData.get("pay_succ_time")));
                //获取转账手续费 单位为分 转换成元
                BigDecimal amt = BigDecimal.valueOf(Double.valueOf(wxQueryBankData.get("cmms_amt")) / 100);
                driverCashDto.setThirdPoundage(amt.doubleValue());
                //记录平台流水提现和提现手续费记录
                ResponseData<SysAccountPlatformDto> responseData = sysAccountPlatformService.get(MapUtils.build("appid",
                        driverCashDto.getAppid()));
                //获取平台信息
                if (!responseData.isSuccess() || responseData.getData() == null) {
                    return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "获取不到平台信息");
                }
                SysAccountPlatformDto accountPlatformDto = responseData.getData();
                //获取平台初始余额
                BigDecimal cashBalance = accountPlatformDto.getCashBalance();

                //保存平台提现到微信的手续费流水记录
                FinanceWithdrawalDto financeWithdrawalFare = new FinanceWithdrawalDto();
                financeWithdrawalFare.setUuid(StringUtils.buildUUID());
                financeWithdrawalFare.setAmount(amt);
                financeWithdrawalFare.setBusinessUuid(driverCashDto.getUuid());
                financeWithdrawalFare.setFinanceOutflow(accountPlatformDto.getUuid());
                financeWithdrawalFare.setCourse(FinanceConstant.WITHDRAWAL_POUNDAGE);
                financeWithdrawalFare.setStartBalance(cashBalance);
                cashBalance = cashBalance.subtract(amt);
                financeWithdrawalFare.setFinalBalance(cashBalance);
                financeWithdrawalFare.setDescription("平台提现到司机银行卡账户支付手续费" + amt + "元");
                financeWithdrawalFare.setCreateOn(new Date());
                financeWithdrawalService.add(financeWithdrawalFare);

                //提现金额
                BigDecimal amount = BigDecimal.valueOf(driverCashDto.getActualAmount());
                //保存平台提现到微信的流水记录
                FinanceWithdrawalDto financeWithdrawal = new FinanceWithdrawalDto();
                financeWithdrawal.setUuid(StringUtils.buildUUID());
                financeWithdrawal.setAmount(amount);
                financeWithdrawal.setBusinessUuid(driverCashDto.getUuid());
                financeWithdrawal.setFinanceOutflow(accountPlatformDto.getUuid());
                financeWithdrawal.setCourse(FinanceConstant.WITHDRAWAL_TO_BANK_CARD);
                financeWithdrawal.setStartBalance(cashBalance);
                cashBalance = cashBalance.subtract(amount);
                financeWithdrawal.setFinalBalance(cashBalance);
                financeWithdrawal.setDescription("平台提现到司机银行卡账户支付" + amount + "元");
                financeWithdrawal.setCreateOn(new Date());
                financeWithdrawalService.add(financeWithdrawal);

                //保存平台账户
                accountPlatformDto.setCashBalance(cashBalance);
                accountPlatformDto.setUpdateOn(new Date());
                sysAccountPlatformService.edit(accountPlatformDto);

                //设置第三方打款状态为打款成功
                driverCashDto.setThirdPayStatus(DriverCashDto.THIRD_STATUS_SUCCESS);
                //设置提现状态为提现成功
                driverCashDto.setWithdrawalStatus(DriverCashDto.WITHDRAWAL_STATUS_SUCCESS);
            }
            //打款失败
            if ("FAILED".equals(wxQueryBankData.get("status"))) {
                //修改第三方打款状态 为失败
                driverCashDto.setThirdPayStatus(DriverCashDto.THIRD_STATUS_FAILURE);
                //失败原因
                driverCashDto.setThirdReason(wxQueryBankData.get("reason"));
            }
            driverCashDto.setUpdateOn(new Date());
            //保存修改
            driverCashService.edit(driverCashDto);
        }
        return ResponseData.buildSuccessResponse("查询打款状态成功", Boolean.TRUE);
    }

    @Override
    public ResponseData<Boolean> dataRepair(String uuid) {
        DriverCashDto driverCashDto = driverCashService.get(uuid).getData();
        log.info("流水号：{} 银行卡提现成功，开始修复提现流水", driverCashDto.getSerialNum());
        //打款成功时间
        driverCashDto.setWithdrawalFinishTime(new Date());
        driverCashDto.setThirdPoundage(0.0D);
        //记录平台流水提现和提现手续费记录
        ResponseData<SysAccountPlatformDto> responseData = sysAccountPlatformService.get(MapUtils.build("appid",
                driverCashDto.getAppid()));
        //获取平台信息
        if (!responseData.isSuccess() || responseData.getData() == null) {
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "获取不到平台信息");
        }
        SysAccountPlatformDto accountPlatformDto = responseData.getData();
        //获取平台初始余额
        BigDecimal cashBalance = accountPlatformDto.getCashBalance();

        //提现金额
        BigDecimal amount = BigDecimal.valueOf(driverCashDto.getActualAmount());
        //保存平台提现到微信的流水记录
        FinanceWithdrawalDto financeWithdrawal = new FinanceWithdrawalDto();
        financeWithdrawal.setUuid(StringUtils.buildUUID());
        financeWithdrawal.setAmount(amount);
        financeWithdrawal.setBusinessUuid(driverCashDto.getUuid());
        financeWithdrawal.setFinanceOutflow(accountPlatformDto.getUuid());
        financeWithdrawal.setCourse(FinanceConstant.WITHDRAWAL_TO_BANK_CARD);
        financeWithdrawal.setStartBalance(cashBalance);
        cashBalance = cashBalance.subtract(amount);
        financeWithdrawal.setFinalBalance(cashBalance);
        financeWithdrawal.setDescription("平台提现到司机银行卡账户支付" + amount + "元");
        financeWithdrawal.setCreateOn(new Date());
        financeWithdrawalService.add(financeWithdrawal);

        //保存平台账户
        accountPlatformDto.setCashBalance(cashBalance);
        accountPlatformDto.setUpdateOn(new Date());
        sysAccountPlatformService.edit(accountPlatformDto);

        //设置第三方打款状态为打款成功
        driverCashDto.setThirdPayStatus(DriverCashDto.THIRD_STATUS_SUCCESS);
        //设置提现状态为提现成功
        driverCashDto.setWithdrawalStatus(DriverCashDto.WITHDRAWAL_STATUS_SUCCESS);
        driverCashDto.setUpdateOn(new Date());
        log.info("流水号：{} 银行卡提现成功，结束修复提现流水", driverCashDto.getSerialNum());
        //保存修改
        return driverCashService.edit(driverCashDto);
    }
}
